1 Run NGSadmix Steps

1.2 Run NGSadmix

# run k=2-5 (run_NGSadmix.sh)
for i in {2..5} 
do 
NGSadmix -likes /home/ktist/ph/data/new_vcf/MD7000/beagle/PH_maf05_pruned.BEAGLE.PL.gz -K $i -o /home/ktist/ph/data/NGSadmix/Ph_pruned_maf05_k$i -P 8 
done 

1.3 Run evalAdmix (locally)

#evalAdmix_runlocal.sh

evalAdmix -beagle Data/ngsadmix/PH_maf05_pruned_BEAGLE.PL.gz -fname Data/ngsadmix/PH_pruned_maf05_k2.fopt.gz -qname Data/ngsadmix/PH_pruned_maf05_k2.qopt -P 8 -o output.corres.k2.txt

2 Results from NGSadmix

source("../Rscripts/BaseScripts.R")
source("../Rscripts/visFuns.R")

library(tidyverse)
library(tibble)

#Output files
qfiles<-list.files("../Data/ngsadmix/",pattern=".qopt")

ofiles<-list.files("../Data/ngsadmix/",pattern="output.corres")

#population info
pop<-read.csv("../Data/Sample_metadata_892pops.csv")

pop$Population.Year<-factor(pop$Population.Year, levels=c("TB91","TB96","TB06","TB17","PWS91","PWS96","PWS07","PWS17","SS96","SS06","SS17","BC17","WA17","CA17"))

poporder<-paste(pop$Population.Year[order(pop$Population.Year)])
pop_order<-c("TB91","TB96","TB06","TB17","PWS91","PWS96","PWS07","PWS17","SS96","SS06","SS17","BC17","WA17","CA17")

#color for populations
#levels=c("TB","PWS","SS", "BC","WA","CA"))
#colors= cols ("#56b4e9" "#cc79a7" "#009e73" "#0072b2" "#d55e00" "#e69f00" "#f0e442")

for (i in 1:length(qfiles)){
    # extract K from the file name
    oname<-ofiles[i]
    k<-as.integer(substr(oname, 16,17))
    
    #read the qopt file for k=k
    q<-read.table(paste0("../Data/ngsadmix/", qfiles[i]))
    
    #order according to population and plot the NGSadmix results
    q$id<-pop$Population.Year
    q<-q[order(q$id),]
    
    ord<-orderInds(pop = as.vector(poporder), q = q[,1:(i+1)])
    
    xlabels<-data.frame(x=tapply(1:length(poporder),list(poporder), mean))
    xlabels$pop<-factor(rownames(xlabels), levels=pop_order)
    xlabels<-xlabels[order(xlabels$pop),]
    
    # c('PWS color', 'TB color', 'CA color" )
    #if (i==1|i==2) colors=c(4,2,7)
    if (i==1|i==2) colors=c(2,4,7)
    #colors<-c("#cc79a7","#56b4e9", "#e69f00")
    #if (i==3) colors=c(5,4,7,2,3) 
    if (i==3) colors=c(5,2,7,4,3) 
    if (i==4) colors=c(4,2,5,7,3)

    {png(paste0("../Output/ngsadmix/Admix_plot_k",k,".png"), height = 3.5, width=8, unit="in", res=300)
    barplot(t(q[,1:(i+2)])[,ord],col=colors,space=0,border=NA,xaxt="n",xlab="Population",ylab=paste0("Admixture proportions for K=",k))
    text(xlabels$x,-0.05,xlabels$pop,xpd=T, srt=90, adj=1,cex=0.8)
    abline(v=cumsum(sapply(unique(poporder[ord]),function(x){sum(pop[ord,"Population.Year"]==x)})),col=1,lwd=1.2)
    dev.off()}
    
    #Plot the correlation matrix from evalAdmix
    r<-read.table(paste0("../Data/ngsadmix/",ofiles[i]))
    
    # Plot correlation of residuals
    {pdf(paste0("../Output/ngsadmix/evalAdmix_corplot_k",k,".pdf"), height = 8, width=10)
    plotCorRes(cor_mat = r, pop = as.vector(pop[,"Population.Year"]), ord = ord, title=paste0("Evaluation of admixture proportions with K=",k), max_z=0.1, min_z=-0.1)
    dev.off()}
}

  • Correlation of residuals


3 Use Clumpak to choose the best K

3.1 Run NGSadmix 10 times for each K (K= 3 & 4)

  • see RunNGSadmix.sh

3.2 Compile all likelihood numbers from log files into 1 (logfile)

#linux code (won't work for unix)
(for log in `ls *.log`; do grep -oP 'Ph_pruned_maf05_\K[^ ]+|like=\K[^ ]+' $log; done) > logfile_k3
(for log in `ls *.log`; do grep -oP 'Ph_pruned_maf05_\K[^ ]+|like=\K[^ ]+' $log; done) > logfile_k4

3.3 Read ‘logfile’ & create an input file for Clumpak

log2<-read.table("../Data/ngsadmix/logfile_k2", sep="\t", header =FALSE)
log3<-read.table("../Data/ngsadmix/logfile_k3", sep="\t", header =FALSE)
log4<-read.table("../Data/ngsadmix/logfile_k4", sep="\t", header =FALSE)
logk2<-log2[c(FALSE,TRUE),]
logk3<-log3[c(FALSE,TRUE),]
logk4<-log4[c(FALSE,TRUE),]

logs<-data.frame(K=c(rep(2, times=10),rep(3, times=10), rep(4, times=10)), Liklihood=c(logk2,logk3, logk4))
write.table(logs, "../Output/ngsadmix/logs.txt", sep="\t", row.names = F, col.names = F, quote=F)
# DO NOT use special character in the file name
#Must have at least three K values

#upload the logs.txt to Clumpak website
# http://clumpak.tau.ac.il

#'Estimating the Best K (from Clumpak)'

# The method of Evanno enables the user to identify a single k value, out of a range of K values, which captures the uppermost 
# level of structure. This method was purposed by Evonno et al. in 2005 (Molecular Ecology 14, 2005). In addition, we also use
# ln(Pr(X|K) #values in order to identify the k for which Pr(K=k) is highest (as described in STRUCTURE's manual, section 5.1).

#STRUCTURE manual
#' it is not infrequent that in real data the value of our model choice criterion continues to increase with increasing K. 
# Then it usually makes sense to focus on values of K that capture most of the structure in the data and that seem 
# biologically sensible.'


# plot admix values
  • Resuls from CLUMPAK
    “Optimal K by Evanno is: 3”
LS0tCnRpdGxlOiAiTkdTQWRtaXgiCm91dHB1dCI6IGh0bWxfbm90ZWJvb2sKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICAgIHRvYzogdHJ1ZSAKICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgICB0aGVtZTogbHVtZW4KICAgICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQojIFJ1biBOR1NhZG1peCBTdGVwcwoKIyMgUHJ1bmUgU05QczogVXNpbmcgUGxpbmsgdG8gcHJ1bmUgaGlnaGx5IGxpbmtlZCBzbnBzICAKCiogUGxpbmsgb3V0cHV0IGZpbGU6IFBIX21hZjA1X3BydW5lXzUwLjUuMC41LnBydW5lLmluCiAgICAtIE5lZWQgdG8gcmVmb3JtYXQgdGhlIHBsaW5rIG91dHB1dCAoeHh4LnBydW5lLmluKSBmaWxlIHRvIGEgYmVkIGZvcm1hdCBpbiBvcmRlciB0byBzdWJzZXQgYSB2Y2YgZmlsZSAgCmBgYHtiYXNoIGV2YWw9RkFMU0UsIGVjaG89VFJVRX0KI1JlZm9ybWF0IHBydW4uaW4gZmlsZSB3aXRoIHJ1bm5pbmcgdGhlIHJlZm9ybWF0X3BydW5pbi5SClIKc291cmNlKCJyZWZvcm1hdF9wcnVuaW4uUiIpCnJlZm9ybWF0X3BydW5pbigicGgvZGF0YS9uZXdfdmNmL01ENzAwMC9wcnVuZWQvUEhfbWFmMDVfcHJ1bmVfNTAuNS4wLjUucHJ1bmUuaW4iKQojb3V0cHV0IHBoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvcHJ1bmVkL1BIX21hZjA1X3BydW5lXzUwLjUuMC41LnBydW5lLmluLnNpdGVzLnR4dApxdWl0KCkKCiMjIFVzZSBiY2Z0b29scyB0byBzdWJzZXQgdGhlIFZDRiBmaWxlIHdpdGggLnBydW5lLmluLnN1dGVzLnR4dApiY2Z0b29scyB2aWV3IC1SIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvcHJ1bmVkL1BIX21hZjA1X3BydW5lXzUwLjUuMC41LnBydW5lLmluLnNpdGVzLnR4dCAgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9QSF9EUDYwMF83MDAwX21pblEyMF9taW5NUTMwX05TMC41X21hZjA1LnZjZi5neiA+IC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvcHJ1bmVkL1BIX0RQNjAwXzcwMDBfTlMwLjVfbWFmMDVfcHJ1bmVkLnZjZgpiZ3ppcCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL3BydW5lZC9QSF9EUDYwMF83MDAwX05TMC41X21hZjA1X3BydW5lZC52Y2YKCiNDcmVhdGUgYmVhZ2xlIGZpbGVzIChjcmVhdGVfYmVhZ2xlLnNoKQojZS5nLiBkbyBjaHJvbW9zb21lIGJ5IGNocm9tb3NvbWUKdmNmdG9vbHMgLS1nenZjZiAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL3BydW5lZC9QSF9EUDYwMF83MDAwX05TMC41X21hZjA1X3BydW5lZC52Y2YuZ3ogLS1jaHIgY2hyMSAtLW91dCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9wcnVuZWRfYzEgLS1CRUFHTEUtUEwgCgojIHJlbW92ZSB0aGUgaGVhZCBmcm9tIGNocjItMjYgKHNsdXJtIHNjcmlwdHMgZG8gbm90IHdvcmssIHNvIHJ1biB0aGUgY29tbWFuZCBvbiB0aGUgdGVybWluYWwpIChjb21iaW5lZF9iZWFnbGUuc2gpCnNlZCAtZSAnMSwgMWQnIDwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfcHJ1bmVkX2MyLkJFQUdMRS5QTCAgPiAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMi5CRUFHTEUuUEwgCgojQ29tYmluZWQgYWxsIGludG8gb25lIGZpbGUKY2F0IC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX3BydW5lZF9jMS5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzIuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MzLkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jNC5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzUuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2M2LkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jNy5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzguQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2M5LkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMTAuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MxMS5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzEyLkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMTMuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MxNC5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzE1LkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMTYuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MxNy5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzE4LkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMTkuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MyMC5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzIxLkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMjIuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MyMy5CRUFHTEUuUEwgL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbm9oZWFkZXJfYzI0LkJFQUdMRS5QTCAvaG9tZS9rdGlzdC9waC9kYXRhL25ld192Y2YvTUQ3MDAwL2JlYWdsZS9QSF9ub2hlYWRlcl9jMjUuQkVBR0xFLlBMIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX25vaGVhZGVyX2MyNi5CRUFHTEUuUEwgID4gL2hvbWUva3Rpc3QvcGgvZGF0YS9uZXdfdmNmL01ENzAwMC9iZWFnbGUvUEhfbWFmMDVfcHJ1bmVkX0JFQUdMRS5QTCAKCmJnemlwIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX21hZjA1X3BydW5lZF9CRUFHTEUuUEwgCgpgYGAKCiMjIFJ1biBOR1NhZG1peCAgCgpgYGB7YmFzaH0KIyBydW4gaz0yLTUgKHJ1bl9OR1NhZG1peC5zaCkKZm9yIGkgaW4gezIuLjV9IApkbyAKTkdTYWRtaXggLWxpa2VzIC9ob21lL2t0aXN0L3BoL2RhdGEvbmV3X3ZjZi9NRDcwMDAvYmVhZ2xlL1BIX21hZjA1X3BydW5lZC5CRUFHTEUuUEwuZ3ogLUsgJGkgLW8gL2hvbWUva3Rpc3QvcGgvZGF0YS9OR1NhZG1peC9QaF9wcnVuZWRfbWFmMDVfayRpIC1QIDggCmRvbmUgCgpgYGAKCgojIyBSdW4gZXZhbEFkbWl4IChsb2NhbGx5KQpgYGB7YmFzaH0KI2V2YWxBZG1peF9ydW5sb2NhbC5zaAoKZXZhbEFkbWl4IC1iZWFnbGUgRGF0YS9uZ3NhZG1peC9QSF9tYWYwNV9wcnVuZWRfQkVBR0xFLlBMLmd6IC1mbmFtZSBEYXRhL25nc2FkbWl4L1BIX3BydW5lZF9tYWYwNV9rMi5mb3B0Lmd6IC1xbmFtZSBEYXRhL25nc2FkbWl4L1BIX3BydW5lZF9tYWYwNV9rMi5xb3B0IC1QIDggLW8gb3V0cHV0LmNvcnJlcy5rMi50eHQKCmBgYAoKCiMgUmVzdWx0cyBmcm9tIE5HU2FkbWl4CgpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzb3VyY2UoIi4uL1JzY3JpcHRzL0Jhc2VTY3JpcHRzLlIiKQpzb3VyY2UoIi4uL1JzY3JpcHRzL3Zpc0Z1bnMuUiIpCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0aWJibGUpCgojT3V0cHV0IGZpbGVzCnFmaWxlczwtbGlzdC5maWxlcygiLi4vRGF0YS9uZ3NhZG1peC8iLHBhdHRlcm49Ii5xb3B0IikKCm9maWxlczwtbGlzdC5maWxlcygiLi4vRGF0YS9uZ3NhZG1peC8iLHBhdHRlcm49Im91dHB1dC5jb3JyZXMiKQoKI3BvcHVsYXRpb24gaW5mbwpwb3A8LXJlYWQuY3N2KCIuLi9EYXRhL1NhbXBsZV9tZXRhZGF0YV84OTJwb3BzLmNzdiIpCgpwb3AkUG9wdWxhdGlvbi5ZZWFyPC1mYWN0b3IocG9wJFBvcHVsYXRpb24uWWVhciwgbGV2ZWxzPWMoIlRCOTEiLCJUQjk2IiwiVEIwNiIsIlRCMTciLCJQV1M5MSIsIlBXUzk2IiwiUFdTMDciLCJQV1MxNyIsIlNTOTYiLCJTUzA2IiwiU1MxNyIsIkJDMTciLCJXQTE3IiwiQ0ExNyIpKQoKcG9wb3JkZXI8LXBhc3RlKHBvcCRQb3B1bGF0aW9uLlllYXJbb3JkZXIocG9wJFBvcHVsYXRpb24uWWVhcildKQpwb3Bfb3JkZXI8LWMoIlRCOTEiLCJUQjk2IiwiVEIwNiIsIlRCMTciLCJQV1M5MSIsIlBXUzk2IiwiUFdTMDciLCJQV1MxNyIsIlNTOTYiLCJTUzA2IiwiU1MxNyIsIkJDMTciLCJXQTE3IiwiQ0ExNyIpCgojY29sb3IgZm9yIHBvcHVsYXRpb25zCiNsZXZlbHM9YygiVEIiLCJQV1MiLCJTUyIsICJCQyIsIldBIiwiQ0EiKSkKI2NvbG9ycz0gY29scyAoIiM1NmI0ZTkiICIjY2M3OWE3IiAiIzAwOWU3MyIgIiMwMDcyYjIiICIjZDU1ZTAwIiAiI2U2OWYwMCIgIiNmMGU0NDIiKQoKZm9yIChpIGluIDE6bGVuZ3RoKHFmaWxlcykpewogICAgIyBleHRyYWN0IEsgZnJvbSB0aGUgZmlsZSBuYW1lCiAgICBvbmFtZTwtb2ZpbGVzW2ldCiAgICBrPC1hcy5pbnRlZ2VyKHN1YnN0cihvbmFtZSwgMTYsMTcpKQogICAgCiAgICAjcmVhZCB0aGUgcW9wdCBmaWxlIGZvciBrPWsKICAgIHE8LXJlYWQudGFibGUocGFzdGUwKCIuLi9EYXRhL25nc2FkbWl4LyIsIHFmaWxlc1tpXSkpCiAgICAKICAgICNvcmRlciBhY2NvcmRpbmcgdG8gcG9wdWxhdGlvbiBhbmQgcGxvdCB0aGUgTkdTYWRtaXggcmVzdWx0cwogICAgcSRpZDwtcG9wJFBvcHVsYXRpb24uWWVhcgogICAgcTwtcVtvcmRlcihxJGlkKSxdCiAgICAKICAgIG9yZDwtb3JkZXJJbmRzKHBvcCA9IGFzLnZlY3Rvcihwb3BvcmRlciksIHEgPSBxWywxOihpKzEpXSkKICAgIAogICAgeGxhYmVsczwtZGF0YS5mcmFtZSh4PXRhcHBseSgxOmxlbmd0aChwb3BvcmRlciksbGlzdChwb3BvcmRlciksIG1lYW4pKQogICAgeGxhYmVscyRwb3A8LWZhY3Rvcihyb3duYW1lcyh4bGFiZWxzKSwgbGV2ZWxzPXBvcF9vcmRlcikKICAgIHhsYWJlbHM8LXhsYWJlbHNbb3JkZXIoeGxhYmVscyRwb3ApLF0KICAgIAogICAgIyBjKCdQV1MgY29sb3InLCAnVEIgY29sb3InLCAnQ0EgY29sb3IiICkKICAgICNpZiAoaT09MXxpPT0yKSBjb2xvcnM9Yyg0LDIsNykKICAgIGlmIChpPT0xfGk9PTIpIGNvbG9ycz1jKDIsNCw3KQogICAgI2NvbG9yczwtYygiI2NjNzlhNyIsIiM1NmI0ZTkiLCAiI2U2OWYwMCIpCiAgICAjaWYgKGk9PTMpIGNvbG9ycz1jKDUsNCw3LDIsMykgCiAgICBpZiAoaT09MykgY29sb3JzPWMoNSwyLDcsNCwzKSAKICAgIGlmIChpPT00KSBjb2xvcnM9Yyg0LDIsNSw3LDMpCgogICAge3BuZyhwYXN0ZTAoIi4uL091dHB1dC9uZ3NhZG1peC9BZG1peF9wbG90X2siLGssIi5wbmciKSwgaGVpZ2h0ID0gMy41LCB3aWR0aD04LCB1bml0PSJpbiIsIHJlcz0zMDApCiAgICBiYXJwbG90KHQocVssMTooaSsyKV0pWyxvcmRdLGNvbD1jb2xvcnMsc3BhY2U9MCxib3JkZXI9TkEseGF4dD0ibiIseGxhYj0iUG9wdWxhdGlvbiIseWxhYj1wYXN0ZTAoIkFkbWl4dHVyZSBwcm9wb3J0aW9ucyBmb3IgSz0iLGspKQogICAgdGV4dCh4bGFiZWxzJHgsLTAuMDUseGxhYmVscyRwb3AseHBkPVQsIHNydD05MCwgYWRqPTEsY2V4PTAuOCkKICAgIGFibGluZSh2PWN1bXN1bShzYXBwbHkodW5pcXVlKHBvcG9yZGVyW29yZF0pLGZ1bmN0aW9uKHgpe3N1bShwb3Bbb3JkLCJQb3B1bGF0aW9uLlllYXIiXT09eCl9KSksY29sPTEsbHdkPTEuMikKICAgIGRldi5vZmYoKX0KICAgIAogICAgI1Bsb3QgdGhlIGNvcnJlbGF0aW9uIG1hdHJpeCBmcm9tIGV2YWxBZG1peAogICAgcjwtcmVhZC50YWJsZShwYXN0ZTAoIi4uL0RhdGEvbmdzYWRtaXgvIixvZmlsZXNbaV0pKQogICAgCiAgICAjIFBsb3QgY29ycmVsYXRpb24gb2YgcmVzaWR1YWxzCiAgICB7cGRmKHBhc3RlMCgiLi4vT3V0cHV0L25nc2FkbWl4L2V2YWxBZG1peF9jb3JwbG90X2siLGssIi5wZGYiKSwgaGVpZ2h0ID0gOCwgd2lkdGg9MTApCiAgICBwbG90Q29yUmVzKGNvcl9tYXQgPSByLCBwb3AgPSBhcy52ZWN0b3IocG9wWywiUG9wdWxhdGlvbi5ZZWFyIl0pLCBvcmQgPSBvcmQsIHRpdGxlPXBhc3RlMCgiRXZhbHVhdGlvbiBvZiBhZG1peHR1cmUgcHJvcG9ydGlvbnMgd2l0aCBLPSIsayksIG1heF96PTAuMSwgbWluX3o9LTAuMSkKICAgIGRldi5vZmYoKX0KfQoKCmBgYAoKIVtdKC4uL091dHB1dC9uZ3NhZG1peC9BZG1peF9wbG90X2syX3NtYWxsLnBuZykKCiogQ29ycmVsYXRpb24gb2YgcmVzaWR1YWxzCgohW10oLi4vT3V0cHV0L25nc2FkbWl4L2V2YWxBZG1peF9jb3JwbG90X2syLnBuZykKCgoKIVtdKC4uL091dHB1dC9uZ3NhZG1peC9BZG1peF9wbG90X2szX3NtYWxsLnBuZykKCiFbXSguLi9PdXRwdXQvbmdzYWRtaXgvZXZhbEFkbWl4X2NvcnBsb3RfazMucG5nKQoKCiFbXSguLi9PdXRwdXQvbmdzYWRtaXgvQWRtaXhfcGxvdF9rNF9zbWFsbC5wbmcpCgohW10oLi4vT3V0cHV0L25nc2FkbWl4L2V2YWxBZG1peF9jb3JwbG90X2s0LnBuZykKCjxicj4KCiMgVXNlIENsdW1wYWsgdG8gY2hvb3NlIHRoZSBiZXN0IEsKKiBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2FsZXhrcm9obi9BbWFyZ29zYVZvbGVUdXRvcmlhbHMvYmxvYi9tYXN0ZXIvbmdzQWRtaXhfdHV0b3JpYWwubWQKCiMjIFJ1biBOR1NhZG1peCAxMCB0aW1lcyBmb3IgZWFjaCBLIChLPSAzICYgNCkKKiBzZWUgUnVuTkdTYWRtaXguc2gKCiMjIENvbXBpbGUgYWxsIGxpa2VsaWhvb2QgbnVtYmVycyBmcm9tIGxvZyBmaWxlcyBpbnRvIDEgKGxvZ2ZpbGUpCgpgYGB7YmFzaCBldmFsPUZBTFNFfQojbGludXggY29kZSAod29uJ3Qgd29yayBmb3IgdW5peCkKKGZvciBsb2cgaW4gYGxzICoubG9nYDsgZG8gZ3JlcCAtb1AgJ1BoX3BydW5lZF9tYWYwNV9cS1teIF0rfGxpa2U9XEtbXiBdKycgJGxvZzsgZG9uZSkgPiBsb2dmaWxlX2szCihmb3IgbG9nIGluIGBscyAqLmxvZ2A7IGRvIGdyZXAgLW9QICdQaF9wcnVuZWRfbWFmMDVfXEtbXiBdK3xsaWtlPVxLW14gXSsnICRsb2c7IGRvbmUpID4gbG9nZmlsZV9rNApgYGAKCgojIyBSZWFkICdsb2dmaWxlJyAmIGNyZWF0ZSBhbiBpbnB1dCBmaWxlIGZvciBDbHVtcGFrCiogaHR0cDovL2NsdW1wYWsudGF1LmFjLmlsL2Jlc3RLLmh0bWwgIAoqIFVwbG9hZCB0aGUgbG9nIHByb2JhYmlsaXR5IHRhYmxlIGZpbGUgdG8gdGhlIHdlYnNpdGUgYW5kIHN1Ym1pdCB0aGUgZm9ybQoKYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbG9nMjwtcmVhZC50YWJsZSgiLi4vRGF0YS9uZ3NhZG1peC9sb2dmaWxlX2syIiwgc2VwPSJcdCIsIGhlYWRlciA9RkFMU0UpCmxvZzM8LXJlYWQudGFibGUoIi4uL0RhdGEvbmdzYWRtaXgvbG9nZmlsZV9rMyIsIHNlcD0iXHQiLCBoZWFkZXIgPUZBTFNFKQpsb2c0PC1yZWFkLnRhYmxlKCIuLi9EYXRhL25nc2FkbWl4L2xvZ2ZpbGVfazQiLCBzZXA9Ilx0IiwgaGVhZGVyID1GQUxTRSkKbG9nazI8LWxvZzJbYyhGQUxTRSxUUlVFKSxdCmxvZ2szPC1sb2czW2MoRkFMU0UsVFJVRSksXQpsb2drNDwtbG9nNFtjKEZBTFNFLFRSVUUpLF0KCmxvZ3M8LWRhdGEuZnJhbWUoSz1jKHJlcCgyLCB0aW1lcz0xMCkscmVwKDMsIHRpbWVzPTEwKSwgcmVwKDQsIHRpbWVzPTEwKSksIExpa2xpaG9vZD1jKGxvZ2syLGxvZ2szLCBsb2drNCkpCndyaXRlLnRhYmxlKGxvZ3MsICIuLi9PdXRwdXQvbmdzYWRtaXgvbG9ncy50eHQiLCBzZXA9Ilx0Iiwgcm93Lm5hbWVzID0gRiwgY29sLm5hbWVzID0gRiwgcXVvdGU9RikKIyBETyBOT1QgdXNlIHNwZWNpYWwgY2hhcmFjdGVyIGluIHRoZSBmaWxlIG5hbWUKI011c3QgaGF2ZSBhdCBsZWFzdCB0aHJlZSBLIHZhbHVlcwoKI3VwbG9hZCB0aGUgbG9ncy50eHQgdG8gQ2x1bXBhayB3ZWJzaXRlCiMgaHR0cDovL2NsdW1wYWsudGF1LmFjLmlsCgojJ0VzdGltYXRpbmcgdGhlIEJlc3QgSyAoZnJvbSBDbHVtcGFrKScKCiMgVGhlIG1ldGhvZCBvZiBFdmFubm8gZW5hYmxlcyB0aGUgdXNlciB0byBpZGVudGlmeSBhIHNpbmdsZSBrIHZhbHVlLCBvdXQgb2YgYSByYW5nZSBvZiBLIHZhbHVlcywgd2hpY2ggY2FwdHVyZXMgdGhlIHVwcGVybW9zdCAKIyBsZXZlbCBvZiBzdHJ1Y3R1cmUuIFRoaXMgbWV0aG9kIHdhcyBwdXJwb3NlZCBieSBFdm9ubm8gZXQgYWwuIGluIDIwMDUgKE1vbGVjdWxhciBFY29sb2d5IDE0LCAyMDA1KS4gSW4gYWRkaXRpb24sIHdlIGFsc28gdXNlCiMgbG4oUHIoWHxLKSAjdmFsdWVzIGluIG9yZGVyIHRvIGlkZW50aWZ5IHRoZSBrIGZvciB3aGljaCBQcihLPWspIGlzIGhpZ2hlc3QgKGFzIGRlc2NyaWJlZCBpbiBTVFJVQ1RVUkUncyBtYW51YWwsIHNlY3Rpb24gNS4xKS4KCiNTVFJVQ1RVUkUgbWFudWFsCiMnIGl0IGlzIG5vdCBpbmZyZXF1ZW50IHRoYXQgaW4gcmVhbCBkYXRhIHRoZSB2YWx1ZSBvZiBvdXIgbW9kZWwgY2hvaWNlIGNyaXRlcmlvbiBjb250aW51ZXMgdG8gaW5jcmVhc2Ugd2l0aCBpbmNyZWFzaW5nIEsuIAojIFRoZW4gaXQgdXN1YWxseSBtYWtlcyBzZW5zZSB0byBmb2N1cyBvbiB2YWx1ZXMgb2YgSyB0aGF0IGNhcHR1cmUgbW9zdCBvZiB0aGUgc3RydWN0dXJlIGluIHRoZSBkYXRhIGFuZCB0aGF0IHNlZW0gCiMgYmlvbG9naWNhbGx5IHNlbnNpYmxlLicKCgojIHBsb3QgYWRtaXggdmFsdWVzCgoKCmBgYAoKKiBSZXN1bHMgZnJvbSBDTFVNUEFLICAgCioqIk9wdGltYWwgSyBieSBFdmFubm8gaXM6IDMgIioqCgo=